﻿// libuvtest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <conio.h>
#include <uv.h>

void mytimer_cb(uv_timer_t *handle)
{
	printf("mytimer_cb.\n");
}

void myidle_cb(uv_idle_t *handle)
{
	//printf("myidle_cb.\n");
}

void uv_alloc_buf(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
{
	if (handle->data != NULL)
	{
		free(handle->data);
		handle->data = NULL;
	}

	handle->data = malloc(suggested_size + 1);
	buf->base = (char*)handle->data;
	buf->len = suggested_size;
}

void on_uv_udp_send_end(uv_udp_send_t *req, int status)
{
	if (status == 0)
	{
		printf("send successed.\n");
	}

	free(req);
}

void after_uv_udp_recv(uv_udp_t *handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags)
{
	char ip_addr[128];
	uv_ip4_name((struct sockaddr_in*)addr, ip_addr, 128);
	int port = ntohs(((struct sockaddr_in*)addr)->sin_port);
	printf("ip:%s:%d nread = %d\n", ip_addr, port, nread);

	char *str_buf = (char*)handle->data;
	str_buf[nread] = 0;
	printf("recv %s\n", str_buf);

	uv_buf_t w_buf = uv_buf_init((char*)"ping", 4);
	uv_udp_send_t *req = (uv_udp_send_t*)malloc(sizeof(uv_udp_send_t));
	uv_udp_send(req, handle, &w_buf, 1, addr, on_uv_udp_send_end);
}

int main()
{
	uv_loop_t *loop = uv_default_loop();

	uv_timer_t mytimer;
	uv_timer_init(loop, &mytimer);
	uv_timer_start(&mytimer, mytimer_cb, 0, 5000);

	uv_idle_t myidle;
	uv_idle_init(loop, &myidle);
	uv_idle_start(&myidle, myidle_cb);

	uv_udp_t myudp;
	memset(&myudp, 0, sizeof(uv_udp_t));

	uv_udp_init(loop, &myudp);

	struct sockaddr_in addr;
	uv_ip4_addr("0.0.0.0", 6080, &addr);
	uv_udp_bind(&myudp, (const struct sockaddr*)&addr, 0);

	uv_udp_recv_start(&myudp, uv_alloc_buf, after_uv_udp_recv);

	uv_run(loop, UV_RUN_DEFAULT);
	printf("Now quitting.\n");

	uv_loop_close(loop);

	_getch();
}
